package com.kalix.training.departments.biz;

import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import com.kalix.framework.core.api.persistence.JsonData;
import com.kalix.framework.core.api.persistence.JsonStatus;
import com.kalix.framework.core.impl.biz.ShiroGenericBizServiceImpl;
import com.kalix.training.departments.api.biz.IDepartmentsBeanService;
import com.kalix.training.departments.api.dao.IDepartmentsBeanDao;
import com.kalix.training.departments.api.dto.DepartmentsDTO;
import com.kalix.training.departments.api.dto.DepartmentsTreeDTO;
import com.kalix.training.departments.entities.DepartmentsBean;


import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class DepartmentsBeanServiceImpl extends ShiroGenericBizServiceImpl<IDepartmentsBeanDao, DepartmentsBean>
        implements IDepartmentsBeanService {
    /**
     * 院系树
     */
    @Override
    public DepartmentsTreeDTO getAllDepByParentId(long parentId) {
        DepartmentsTreeDTO root = new DepartmentsTreeDTO();
        root.setId(-1L);
        List<DepartmentsBean> beans = new ArrayList<>();
        String sql = "select s from DepartmentsBean s where 1=1";
        if (parentId != -1) {
            sql += " and s.parentId=" + parentId;
        }
        sql += " order by s.creationDate desc";
        beans = dao.find(sql);

        if (beans != null && beans.size() > 0) {
            List<DepartmentsBean> rootElements = getRootElements(beans);
            if (rootElements != null && rootElements.size() > 0) {
                for (DepartmentsBean rootElement : rootElements) {
//                    Mapper mapper = new DozerBeanMapper();
                    Mapper mapper = DozerBeanMapperBuilder.buildDefault();
                    DepartmentsTreeDTO departmentsTreeDTO = mapper.map(rootElement, DepartmentsTreeDTO.class);
                    departmentsTreeDTO.setLeaf(rootElement.getIsLeaf() == 0 ? false : true);
                    departmentsTreeDTO.setParentName("根目录");
                    getChilden(departmentsTreeDTO, beans, mapper);
                    root.getChildren().add(departmentsTreeDTO);
                }
            }
        }
        return root;
    }

    /**
     * 递归函数加载子节点
     *
     * @param root
     * @param elements
     */
    private void getChilden(DepartmentsTreeDTO root, List<DepartmentsBean> elements, Mapper mapper) {
        List<DepartmentsTreeDTO> children = new ArrayList<DepartmentsTreeDTO>();
        for (DepartmentsBean departmentsBean : elements) {
            if (root.getId() != -1 && (root.getId() == departmentsBean.getParentId())) {
                DepartmentsTreeDTO departmentsTreeDTO = mapper.map(departmentsBean, DepartmentsTreeDTO.class);
                departmentsTreeDTO.setLeaf(departmentsBean.getIsLeaf() == 0 ? false : true);
                departmentsTreeDTO.setParentName(root.getContent());
                children.add(departmentsTreeDTO);
                if (departmentsBean.getIsLeaf() == 0) {
                    getChilden(departmentsTreeDTO, elements, mapper);
                }
            }
        }
        root.setChildren(children);
    }

    /**
     * 获得所有根节点
     *
     * @param elements
     * @return
     */
    private List<DepartmentsBean> getRootElements(List<DepartmentsBean> elements) {
        List<DepartmentsBean> roots = new ArrayList<DepartmentsBean>();
        for (DepartmentsBean element : elements) {
            if (element.getParentId() == -1) {
                roots.add(element);
            }
        }
        return roots;
    }

    /**
     * 获取院系信息，并以级联形式返回数据
     *
     * @return
     */
    @Override
    public JsonData getDepCascader() {
        List<DepartmentsBean> qlist = dao.find("select d from DepartmentsBean d");
        List<DepartmentsBean> listParents = qlist.stream().filter(db -> db.getParentId() == -1).collect(Collectors.toList());
        List<DepartmentsDTO> list = new ArrayList<>();
        for (DepartmentsBean one : listParents) {
            DepartmentsDTO dd = new DepartmentsDTO();
            dd.setValue(Long.toString(one.getId()));
            dd.setLabel(one.getContent());
            dd.setChildren(getDepartmentsChilden(one, qlist));
            list.add(dd);
        }
        JsonData jsonData = new JsonData();
        jsonData.setTotalCount((long) list.size());
        jsonData.setData(list);
        return jsonData;
    }

    /**
     * 院系删除节点以及子节点的功能
     *
     * @param id
     */
    @Override
    public JsonStatus deleteAllDep(long id) {
        dao.remove(id);
        deleteAllChildens(id);
        JsonStatus jsonStatus = new JsonStatus();
        jsonStatus.setSuccess(true);
        jsonStatus.setMsg("删除成功！");
        return jsonStatus;
    }

    /**
     * @param pid
     * @return 计算当前父节点下的节点的最大代码（code）返回处理后的新code
     */
    @Override
    public String getCodeByPid(long pid) {
        List<DepartmentsBean> list = dao.find("select d from DepartmentsBean d where d.parentId=?1", pid);
        Integer num = getLevelByPid(pid, 1);
        if (pid != -1) {
            DepartmentsBean dep = dao.get(pid);
            StringBuilder code = new StringBuilder(dep.getCode());
            Integer codeNum = 0;
            if (list.size() != 0) {
                codeNum = Integer.parseInt(list.get(0).getCode().substring((num - 1) * 2, num * 2));
                for (DepartmentsBean db : list) {
                    if (codeNum < Integer.parseInt(db.getCode().substring(num * 2 - 2, num * 2))) {
                        codeNum = Integer.parseInt(db.getCode().substring(num * 2 - 2, num * 2));
                    }
                }
            }
            codeNum = codeNum + 1;
            if (codeNum < 10) {
                code = code.replace((num - 1) * 2, num * 2, "0" + codeNum);
                return code + "";
            } else {
                code = code.replace((num - 1) * 2, num * 2, codeNum.toString());
                return code + "";
            }
        } else {
            Integer codeNum = 0;
            if (list.size() != 0) {
                codeNum = Integer.parseInt(list.get(0).getCode().substring((num - 1) * 2, num * 2));
                for (DepartmentsBean db : list) {
                    if (codeNum < Integer.parseInt(db.getCode().substring(num * 2 - 2, num * 2))) {
                        codeNum = Integer.parseInt(db.getCode().substring(num * 2 - 2, num * 2));
                    }
                }
            }
            codeNum = codeNum + 1;
            if (codeNum < 10) {
                String code = "0" + codeNum + "000000";
                return code;
            } else {
                String code = codeNum + "000000";
                return code;
            }
        }
    }

    /**
     * @param code 院系的内容
     * @return 通过院系的内容查询相应的院系信息
     */
    @Override
    public JsonData getCodeByContent(String code) {
        List<DepartmentsBean> list = dao.find("select d from DepartmentsBean d where d.code=?1", code);
        JsonData jsondata = new JsonData();
        jsondata.setData(list);
        jsondata.setTotalCount((long) list.size());
        return jsondata;
    }

    @Override
    public JsonStatus getEchoByDid(long did) {
        JsonStatus jsonstatus = new JsonStatus();
        String str = getParentId(did);
        String echo = "";
        String[] strs = str.split(",");
        for (int i = strs.length - 1; i >= 0; i--) {
            echo += strs[i] + ",";
        }
        jsonstatus.setSuccess(true);
        jsonstatus.setTag(echo.substring(0 , echo.length() - 1));
        jsonstatus.setMsg("成功获取数据");
        return jsonstatus;
    }

    private String getParentId(long did) {
        DepartmentsBean departments = dao.get(did);
        String str = did + ",";
        if (departments.getParentId() != -1) {
            str += getParentId(departments.getParentId());
        }
        return str;
    }

    /**
     * 用递归计数获取第几级数据
     *
     * @param pid,num
     * @return
     */
    private Integer getLevelByPid(long pid, Integer num) {
        if (pid == -1) {
            return num;
        } else {
            DepartmentsBean dep = dao.get(pid);
            num++;
            return getLevelByPid(dep.getParentId(), num);
        }
    }

    /**
     * 用递归的方法删除节点下的所有子节点
     *
     * @param id
     */
    private void deleteAllChildens(long id) {
        List<DepartmentsBean> list = dao.find("select d from DepartmentsBean d");
        for (DepartmentsBean dep : list) {
            if (dep.getParentId() == id) {
                dao.remove(dep.getId());
                deleteAllChildens(dep.getId());
            }
        }
    }

    /**
     * 递归方法获取级联子节点
     */
    private List<DepartmentsDTO> getDepartmentsChilden(DepartmentsBean one, List<DepartmentsBean> qlist) {
        List<DepartmentsDTO> list = new ArrayList<>();
        for (DepartmentsBean db : qlist) {
            if (one.getId() == db.getParentId()) {
                DepartmentsDTO dd = new DepartmentsDTO();
                dd.setValue(Long.toString(db.getId()));
                dd.setLabel(db.getContent());
                List<DepartmentsDTO> children = getDepartmentsChilden(db, qlist);
                if (children != null && !children.isEmpty()) {
                    dd.setChildren(children);
                }
                list.add(dd);
            }
        }
        return list;
    }
}
